package com.mfs.proxy.client.transfer.http.response;

import com.mfs.common.enums.CompressEnum;
import com.mfs.common.utills.StringUtil;

import java.nio.charset.Charset;
import java.nio.charset.UnsupportedCharsetException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * Http 响应对象
 *
 * @author mfs
 * @date 2023/7/10 22:34
 **/
public class HttpResponse {
    private HttpResponseLine httpResponseLine = new HttpResponseLine();
    private HttpResponseHeader httpResponseHeader = new HttpResponseHeader();
    private HttpResponseBody httpResponseBody = new HttpResponseBody(this);
    /**
     * chunked 块是没有响应行、响应头的，响应体也不一定完整，理论上不能做任何操作
     * */
    private boolean chunkedBlock = false;

    public HttpResponseLine getHttpResponseLine() {
        return httpResponseLine;
    }

    public void setHttpResponseLine(HttpResponseLine httpResponseLine) {
        this.httpResponseLine = httpResponseLine;
    }

    public HttpResponseHeader getHttpResponseHeader() {
        return httpResponseHeader;
    }

    public void setHttpResponseHeader(HttpResponseHeader httpResponseHeader) {
        this.httpResponseHeader = httpResponseHeader;
    }

    public HttpResponseBody getHttpResponseBody() {
        return httpResponseBody;
    }

    public void setHttpResponseBody(HttpResponseBody httpResponseBody) {
        this.httpResponseBody = httpResponseBody;
    }

    public byte[] getBytes() {
        if (chunkedBlock) {
            return httpResponseBody.getBytes();
        }
        byte[] line = httpResponseLine.getBytes();
        byte[] head = httpResponseHeader.getBytes();
        byte[] body = httpResponseBody.getBytes();
        byte[] res = new byte[line.length + head.length + body.length];
        System.arraycopy(line, 0, res, 0, line.length);
        System.arraycopy(head, 0, res, line.length, head.length);
        System.arraycopy(body, 0, res, line.length + head.length, body.length);
        return res;
    }

    public void setChunkedBlock(boolean chunkedBlock) {
        this.chunkedBlock = chunkedBlock;
    }

    public boolean isChunkedBlock() {
        return chunkedBlock;
    }

    /**
     * 不支持或者没有压缩的会返回default类型，使用default进行对字节解压缩、压缩不会进行任何操作
     * */
    public CompressEnum getCompress() {
        String contentEncoding = httpResponseHeader.getHead("content-encoding");
        String transferEncoding = httpResponseHeader.getHead("transfer-encoding");
        if (contentEncoding.toLowerCase().contains("gzip") || transferEncoding.toLowerCase().contains("gzip")) {
            return CompressEnum.GZIP;
        } else if (contentEncoding.toLowerCase().contains("deflate") || transferEncoding.toLowerCase().contains("deflate")) {
            return CompressEnum.DEFLATE;
        } else {
            // 其他压缩方式暂不支持 todo 支持compress、br压缩方式
            return CompressEnum.DEFAULT;
        }
    }

    /**
     * 获取当前解析的请求体的字符集编码,
     * 获取不到则返回默认字符集
     * */
    public Charset getBodyCharset() {
        String contentType = httpResponseHeader.getHead("content-type");
        if (StringUtil.isNotBlank(contentType)) {
            Pattern pattern = Pattern.compile("charset\\s*=\\s*\\S+;");
            Matcher matcher = pattern.matcher(contentType);
            if (matcher.matches()) {
                String charsetParam = matcher.group();
                if (StringUtil.isNotBlank(charsetParam)) {
                    String charset = charsetParam.replaceAll("charset", "").replace("=", "").replaceAll(";", "").trim();
                    try {
                        return Charset.forName(charset);
                    } catch (UnsupportedCharsetException e) {
                    }
                }
            }
        }
        return Charset.defaultCharset();
    }

    /**
     * 压缩方式
     * */

    @Override
    public String toString() {
        return httpResponseLine + "\r\n" + httpResponseHeader + "\r\n\r\n" + httpResponseBody;
    }
}
